﻿' LibWowArmory
' by Ronald M. Clifford (roncli@roncli.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Web
Imports System.Xml.Serialization

Namespace roncliProductions.LibWowArmory

    Public Class CharacterStatistics
        Inherits WowArmoryData

#Region "Declarations"

        Private csPage As New CharacterStatisticsSchema.page
        Private strRealm As String
        Private strName As String
        Private sRecentStatistics As New List(Of Statistic)
        Private cCategories As New List(Of Category)

#End Region

        ''' <summary>
        ''' The realm the character is on
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Realm() As String
            Get
                Return strRealm
            End Get
            Set(ByVal value As String)
                strRealm = value
            End Set
        End Property

        ''' <summary>
        ''' The name of the character
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Name() As String
            Get
                Return strName
            End Get
            Set(ByVal value As String)
                strName = value
            End Set
        End Property

        ''' <summary>
        ''' The URL that will be used to retrieve the character's statistics from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property URL() As String
            Get
                Return String.Format("http://www.wowarmory.com/character-statistics.xml?r={0}&n={1}", strRealm, strName)
            End Get
        End Property

        ''' <summary>
        ''' Indicates to the inherited class that this request does not require login
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property RequiresLogin() As Boolean
            Get
                Return False
            End Get
        End Property

        ''' <summary>
        ''' The most recent statistics earned by this character
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RecentStatistics() As List(Of Statistic)
            Get
                Return sRecentStatistics
            End Get
        End Property

        ''' <summary>
        ''' The statistic categories for this character
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Categories() As List(Of Category)
            Get
                Return cCategories
            End Get
        End Property

        ''' <summary>
        ''' A constructor to load a character's statistics by realm and character name
        ''' </summary>
        ''' <param name="strRealm"></param>
        ''' <param name="strName"></param>
        ''' <remarks></remarks>
        Public Sub New(ByVal strRealm As String, ByVal strName As String)
            Me.strRealm = strRealm
            Me.strName = strName
            Load()
        End Sub

        ''' <summary>
        ''' Loads the character's statistics from the armory
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            Dim strKey As String = String.Format("LibWowArmory.CharacterStatistics.{0}.{1}", strRealm, strName)
            If Cache.Cache(strKey) Is Nothing Then
                MyBase.Retrieve()

                Dim xsSerializer As New XmlSerializer(csPage.GetType())

                Dim srXML As New StringReader(MyBase.strData)

                csPage = CType(xsSerializer.Deserialize(srXML), CharacterStatisticsSchema.page)

                Cache.Cache.Insert(strKey, csPage, Nothing, Date.UtcNow.AddDays(1), Nothing, Caching.CacheItemPriority.Normal, Nothing)
            Else
                csPage = CType(Cache.Cache(strKey), CharacterStatisticsSchema.page)
            End If

            If csPage Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve statistics for does not exist.")
            End If
            If csPage.characterInfo Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve statistics for does not exist.")
            End If
            If csPage.characterInfo.First().character Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve statistics for does not exist.")
            End If
            If csPage.statistics Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve statistics for does not exist.")
            End If

            For Each sStatistic As CharacterStatisticsSchema.statistic In csPage.statistics.First().summary.First().statistic
                sRecentStatistics.Add(New Statistic(sStatistic.id, sStatistic.name, sStatistic.quantity))
            Next

            For Each cCategory As CharacterStatisticsSchema.rootCategories_category In csPage.statistics.First().rootCategories.First().category
                cCategories.Add(New Category(cCategory.id, cCategory.name, (From c In cCategory.category Select New Subcategory(c.name)).ToList()))
            Next
        End Sub

        ''' <summary>
        ''' A character's statistics for a single category
        ''' </summary>
        ''' <param name="cCategory"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function CategoryStatistics(ByRef cCategory As Category) As CharacterStatisticsCategory
            Return New CharacterStatisticsCategory(strRealm, strName, cCategory.ID)
        End Function

        ''' <summary>
        ''' A class that encapsulates a statistic category
        ''' </summary>
        ''' <remarks></remarks>
        Public Class Category

            Private intID As Integer
            Private strName As String
            Private sSubcategories As List(Of Subcategory)

            ''' <summary>
            ''' The identification number of the category
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property ID() As Integer
                Get
                    Return intID
                End Get
                Set(ByVal value As Integer)
                    intID = value
                End Set
            End Property

            ''' <summary>
            ''' The category's name
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Name() As String
                Get
                    Return strName
                End Get
                Set(ByVal value As String)
                    strName = value
                End Set
            End Property

            ''' <summary>
            ''' The subcategories contained in this category
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Subcategories() As List(Of Subcategory)
                Get
                    Return sSubcategories
                End Get
                Set(ByVal value As List(Of Subcategory))
                    sSubcategories = value
                End Set
            End Property

            ''' <summary>
            ''' A constructor that creates a new statistic category
            ''' </summary>
            ''' <param name="intID"></param>
            ''' <param name="strName"></param>
            ''' <remarks></remarks>
            Public Sub New(ByVal intID As Integer, ByVal strName As String, ByVal sSubcategories As List(Of Subcategory))
                Me.intID = intID
                Me.strName = strName
                Me.sSubcategories = sSubcategories
            End Sub

        End Class

        ''' <summary>
        ''' A class that encapsulates an statistic subcategory
        ''' </summary>
        ''' <remarks></remarks>
        Public Class Subcategory

            Private strName As String

            ''' <summary>
            ''' The subcategory's name
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Name() As String
                Get
                    Return strName
                End Get
                Set(ByVal value As String)
                    strName = value
                End Set
            End Property

            ''' <summary>
            ''' A constructor that creates a new statistic subcategory
            ''' </summary>
            ''' <param name="strName"></param>
            ''' <remarks></remarks>
            Public Sub New(ByVal strName As String)
                Me.strName = strName
            End Sub

        End Class

    End Class

End Namespace